/**
 * @file      config_data.c
 * @brief
 * @version   1.0
 * @date      2023.12.14
 *
 * @copyright Copyright (c) 2018 UCchip Technology Co.,Ltd. All rights reserved.
 *
 * Change Logs:
 * Date          Author       Notes
 * 2023.12.14    mxzou        the first version
 *
 */

#include "config_data.h"
#include "config_api.h"
#include "config_storage.h"
#include "json_to_data.h"
#include "net_prot.h"
#include "uc_log.h"
#include <board.h>
#include <rtdevice.h>
#include <rtthread.h>
#include <string.h>

int parse_gateway_base_cfg(const cJSON *data_json, gw_base_cfg_t *base_cfg)
{
    int ret = 0;
    const cJSON *base_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_BASE_CFG);
    if (!base_cfg_obj)
    {
        return -1;
    }
    ret |= parse_string(base_cfg_obj, COMPANY, base_cfg->company, sizeof(base_cfg->company));
    ret |= parse_uint8_array(base_cfg_obj, DEV_SERIAL, base_cfg->dev_serial, sizeof(base_cfg->dev_serial));
    ret |= parse_uint32(base_cfg_obj, DEV_ID, &base_cfg->dev_id);
    ret |= parse_string(base_cfg_obj, HARDWARE_VERSION, base_cfg->hardware_version, sizeof(base_cfg->hardware_version));
    ret |= parse_string(base_cfg_obj, SOFTWARE_VERSION, base_cfg->software_version, sizeof(base_cfg->software_version));

    return ret;
}

int parse_gateway_auth_cfg(const cJSON *data_json, gw_auth_cfg_t *auth_cfg)
{
    int ret = 0;
    const cJSON *auth_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_AUTH_CFG);
    if (!auth_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint8(auth_cfg_obj, WORK_MODE, &auth_cfg->work_mode);
    ret |= parse_uint8(auth_cfg_obj, GW_VERITY, &auth_cfg->gw_verity);
    ret |= parse_uint16(auth_cfg_obj, KEY_TYPE, &auth_cfg->key_type);
    ret |= parse_string(auth_cfg_obj, KEY, auth_cfg->key, sizeof(auth_cfg->key));

    return ret;
}

int parse_gateway_id_mng_cfg(const cJSON *data_json, gw_id_manager_cfg_t *id_mng_cfg)
{
    int ret = 0;
    const cJSON *id_mng_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_ID_MNG_CFG);
    if (!id_mng_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint32(id_mng_cfg_obj, ASSIGN_START_ADDR, &id_mng_cfg->assign_start_addr);
    ret |= parse_uint32(id_mng_cfg_obj, ASSIGN_END_ADDR, &id_mng_cfg->assign_end_addr);
    ret |= parse_uint32(id_mng_cfg_obj, ADDR_NUM, &id_mng_cfg->addr_num);

    return ret;
}

int parse_gateway_net_policy_cfg(const cJSON *data_json, gw_net_policy_cfg_t *net_policy_cfg)
{
    int ret = 0;
    const cJSON *net_policy_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, NETDEV_POLICY);
    if (!net_policy_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint32(net_policy_cfg_obj, NETDEV_POLICY, &net_policy_cfg->netdev_policy);
    ret |= parse_string(net_policy_cfg_obj, NETDEV_NAME, net_policy_cfg->netdev_name, sizeof(net_policy_cfg->netdev_name));

    return ret;
}

int parse_gateway_net_if_cfg(const cJSON *data_json, gw_net_if_cfg_t *net_if_cfg)
{
    int ret = 0;
    const cJSON *net_if_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, NET_INTERFACE);
    if (!net_if_cfg_obj)
    {
        return -1;
    }
    ret |= parse_string(net_if_cfg_obj, NET_DEV_STATE, net_if_cfg->netdev_state, sizeof(net_if_cfg->netdev_state));
    ret |= parse_uint16(net_if_cfg_obj, STATIC_IP, &net_if_cfg->static_ip);
    ret |= parse_uint8_array(net_if_cfg_obj, MAC_ADDR, net_if_cfg->mac, sizeof(net_if_cfg->mac));
    ret |= parse_string(net_if_cfg_obj, IP_ADDR, net_if_cfg->ip_addr, sizeof(net_if_cfg->ip_addr));
    ret |= parse_string(net_if_cfg_obj, GATEWAY_ADDR, net_if_cfg->gateway_addr, sizeof(net_if_cfg->gateway_addr));
    ret |= parse_string(net_if_cfg_obj, MASK_ADDR, net_if_cfg->mask_addr, sizeof(net_if_cfg->mask_addr));
    ret |= parse_string(net_if_cfg_obj, PRIMARY_DNS, net_if_cfg->primary_dns, sizeof(net_if_cfg->primary_dns));
    ret |= parse_string(net_if_cfg_obj, SECONDARY_DNS, net_if_cfg->secondary_dns, sizeof(net_if_cfg->secondary_dns));

    return ret;
}

int parse_gateway_wifi_cfg(const cJSON *data_json, gw_wifi_cfg_t *wifi_cfg)
{
    int ret = 0;
    const cJSON *wifi_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_WIFI_CFG);
    if (!wifi_cfg_obj)
    {
        return -1;
    }
    ret |= parse_string(wifi_cfg_obj, NET_DEV_STATE, wifi_cfg->netdev_state, sizeof(wifi_cfg->netdev_state));
    ret |= parse_uint16(wifi_cfg_obj, STATIC_IP, &wifi_cfg->static_ip);
    ret |= parse_uint8_array(wifi_cfg_obj, MAC_ADDR, wifi_cfg->mac, sizeof(wifi_cfg->mac));
    ret |= parse_string(wifi_cfg_obj, IP_ADDR, wifi_cfg->ip_addr, sizeof(wifi_cfg->ip_addr));
    ret |= parse_string(wifi_cfg_obj, GATEWAY_ADDR, wifi_cfg->gateway_addr, sizeof(wifi_cfg->gateway_addr));
    ret |= parse_string(wifi_cfg_obj, MASK_ADDR, wifi_cfg->mask_addr, sizeof(wifi_cfg->mask_addr));
    ret |= parse_string(wifi_cfg_obj, PRIMARY_DNS, wifi_cfg->primary_dns, sizeof(wifi_cfg->primary_dns));
    ret |= parse_string(wifi_cfg_obj, SECONDARY_DNS, wifi_cfg->secondary_dns, sizeof(wifi_cfg->secondary_dns));
    ret |= parse_string(wifi_cfg_obj, USERNAME, wifi_cfg->username, sizeof(wifi_cfg->username));
    ret |= parse_string(wifi_cfg_obj, PASSWORD, wifi_cfg->password, sizeof(wifi_cfg->password));

    return ret;
}

int parse_gateway_cat1_cfg(const cJSON *data_json, gw_cat1_cfg_t *cat1_cfg)
{
    int ret = 0;
    const cJSON *cat1_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_CAT1_CFG);
    if (!cat1_cfg_obj)
    {
        return -1;
    }
    ret |= parse_string(cat1_cfg_obj, NET_DEV_STATE, cat1_cfg->netdev_state, sizeof(cat1_cfg->netdev_state));
    ret |= parse_uint8_array(cat1_cfg_obj, MAC_ADDR, cat1_cfg->mac, sizeof(cat1_cfg->mac));
    ret |= parse_string(cat1_cfg_obj, IP_ADDR, cat1_cfg->ip_addr, sizeof(cat1_cfg->ip_addr));
    ret |= parse_string(cat1_cfg_obj, GATEWAY_ADDR, cat1_cfg->gateway_addr, sizeof(cat1_cfg->gateway_addr));
    ret |= parse_string(cat1_cfg_obj, MASK_ADDR, cat1_cfg->mask_addr, sizeof(cat1_cfg->mask_addr));
    ret |= parse_string(cat1_cfg_obj, CAT1_CSQ, cat1_cfg->csq, sizeof(cat1_cfg->csq));
    ret |= parse_string(cat1_cfg_obj, CAT1_CCID, cat1_cfg->ccid, sizeof(cat1_cfg->ccid));
    ret |= parse_string(cat1_cfg_obj, CAT1_CIMI, cat1_cfg->cimi, sizeof(cat1_cfg->cimi));
    ret |= parse_string(cat1_cfg_obj, CAT1_GSN, cat1_cfg->gsn, sizeof(cat1_cfg->gsn));
    ret |= parse_string(cat1_cfg_obj, CAT1_APN, cat1_cfg->apn, sizeof(cat1_cfg->apn));

    return ret;
}

int parse_gateway_bt_cfg(const cJSON *data_json, gw_bt_cfg_t *bt_cfg)
{
    int ret = 0;
    const cJSON *bt_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_BT_CFG);
    if (!bt_cfg_obj)
    {
        return -1;
    }
    ret |= parse_string(bt_cfg_obj, MAC_ADDR, bt_cfg->mac, sizeof(bt_cfg->mac));

    return ret;
}

int parse_gateway_mqtt_server_cfg(const cJSON *data_json, gw_mqtt_server_cfg_t *mqtt_cfg)
{
    int ret = 0;
    const cJSON *mqtt_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_MQTT_CFG);
    if (!mqtt_cfg_obj)
    {
        return -1;
    }
    ret |= parse_string(mqtt_cfg_obj, URL, mqtt_cfg->url, sizeof(mqtt_cfg->url));
    ret |= parse_uint32(mqtt_cfg_obj, MQTT_PORT, &mqtt_cfg->port);
    ret |= parse_string(mqtt_cfg_obj, CLIENT_ID, mqtt_cfg->client_id, sizeof(mqtt_cfg->client_id));
    ret |= parse_string(mqtt_cfg_obj, USERNAME, mqtt_cfg->username, sizeof(mqtt_cfg->username));
    ret |= parse_string(mqtt_cfg_obj, PASSWORD, mqtt_cfg->password, sizeof(mqtt_cfg->password));
    ret |= parse_uint32(mqtt_cfg_obj, MQTT_QOS, &mqtt_cfg->qos);

    return ret;
}

int parse_gateway_data_cfg(const cJSON *data_json, gw_data_cfg_t *data_cfg)
{
    int ret = 0;
    const cJSON *ul_data_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_DATA_CFG);
    if (!ul_data_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint8(ul_data_cfg_obj, UP_ENCODE, &data_cfg->up_encode);
    ret |= parse_uint8(ul_data_cfg_obj, UL_DATA_FLOW, &data_cfg->ul_data_flow);
    ret |= parse_uint8(ul_data_cfg_obj, UL_DATA_PRINT, &data_cfg->ul_data_print);
    ret |= parse_uint8(ul_data_cfg_obj, DL_DATA_PRINT, &data_cfg->dl_data_print);

    return ret;
}

int parse_gateway_wtd_cfg(const cJSON *data_json, gw_wtd_cfg_t *wtd_cfg)
{
    int ret = 0;
    const cJSON *wtd_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_WTD_CFG);
    if (!wtd_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint8(wtd_cfg_obj, WTD_STATE, &wtd_cfg->wtd_state);

    return ret;
}

int parse_gateway_ftp_log_cfg(const cJSON *data_json, gw_ftp_log_cfg_t *log_cfg)
{
    int ret = 0;
    const cJSON *log_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, FTP_LOG);
    if (!log_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint8(log_cfg_obj, FTP_LOG, &log_cfg->ftp_log);
    ret |= parse_uint16(log_cfg_obj, FTP_PORT, &log_cfg->port);
    ret |= parse_string(log_cfg_obj, IP_ADDR, log_cfg->ip_addr, sizeof(log_cfg->ip_addr));
    ret |= parse_string(log_cfg_obj, USERNAME, log_cfg->username, sizeof(log_cfg->username));
    ret |= parse_string(log_cfg_obj, PASSWORD, log_cfg->password, sizeof(log_cfg->password));
    ret |= parse_string(log_cfg_obj, SERVER_PATH, log_cfg->server_path, sizeof(log_cfg->server_path));

    return ret;
}

int parse_gateway_log_switch_cfg(const cJSON *data_json, gw_log_switch_cfg_t *log_switch_cfg)
{
    int ret = 0;
    const cJSON *log_switch_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_LOG_SWITCH_CFG);
    if (!log_switch_cfg_obj)
    {
        return -1;
    }
    ret |= parse_string(log_switch_cfg_obj, GW_LOG_UART, log_switch_cfg->log_uart, sizeof(log_switch_cfg->log_uart));
    ret |= parse_uint8(log_switch_cfg_obj, GW_AP_LOG_OUTPUT, &log_switch_cfg->ap_log_output);

    return ret;
}

int parse_gateway_uart_485_cfg(const cJSON *data_json, gw_uart_485_cfg_t *uart_485_cfg)
{
    int ret = 0;
    const cJSON *uart_485_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_UART_485_CFG);
    if (!uart_485_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint32(uart_485_cfg_obj, GW_UART_485_BAUD, &uart_485_cfg->baud_rate);

    return ret;
}

int parse_gateway_timed_cfg(const cJSON *data_json, gw_timed_cfg_t *timed_cfg)
{
    int ret = 0;
    const cJSON *timed_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_TIMED_CFG);
    if (!timed_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint32(timed_cfg_obj, GW_TIME, &timed_cfg->time);
    ret |= parse_uint32(timed_cfg_obj, GW_UNABNORMAL_TIME, &timed_cfg->abnormal_time);
    ret |= parse_uint32(timed_cfg_obj, GW_ROLL_CALL_TIME, &timed_cfg->roll_call_time);
    ret |= parse_uint32(timed_cfg_obj, GW_ROLL_CALL_RTO, &timed_cfg->rc_rto);

    return ret;
}

int parse_gateway_cfg(const cJSON *data_json, gateway_cfg_t *gw_cfg)
{
    int ret = 0;
    const cJSON *gw_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, GW_CFG);
    if (!gw_cfg_obj)
    {
        return -1;
    }
    // 解析网关基础配置
    ret |= parse_gateway_base_cfg(gw_cfg_obj, &gw_cfg->base_cfg);
    // 解析网关鉴权配置
    ret |= parse_gateway_auth_cfg(gw_cfg_obj, &gw_cfg->auth_cfg);
    // 解析网id管理配置
    ret |= parse_gateway_id_mng_cfg(gw_cfg_obj, &gw_cfg->id_mng_cfg);
    // 解析网关网络配置
    ret |= parse_gateway_net_policy_cfg(gw_cfg_obj, &gw_cfg->net_policy_cfg);
    ret |= parse_gateway_net_if_cfg(gw_cfg_obj, &gw_cfg->net_if_cfg);
    ret |= parse_gateway_wifi_cfg(gw_cfg_obj, &gw_cfg->wifi_cfg);
    ret |= parse_gateway_cat1_cfg(gw_cfg_obj, &gw_cfg->cat1_cfg);
    // 解析网关蓝牙配置
    ret |= parse_gateway_bt_cfg(gw_cfg_obj, &gw_cfg->bt_cfg);
    // 解析网关mqtt服务器配置
    ret |= parse_gateway_mqtt_server_cfg(gw_cfg_obj, &gw_cfg->mqtt_server_cfg);
    // 解析网关WIFI配置
    ret |= parse_gateway_wifi_cfg(gw_cfg_obj, &gw_cfg->wifi_cfg);
    // 解析网关上下行数据配置
    ret |= parse_gateway_data_cfg(gw_cfg_obj, &gw_cfg->data_cfg);
    // 解析网关看门狗配置
    ret |= parse_gateway_wtd_cfg(gw_cfg_obj, &gw_cfg->wtd_cfg);
    // 解析网关log配置
    ret |= parse_gateway_ftp_log_cfg(gw_cfg_obj, &gw_cfg->log_cfg);
    // 解析网关log开关配置
    ret |= parse_gateway_log_switch_cfg(gw_cfg_obj, &gw_cfg->log_switch_cfg);
    // 解析网关uart 485配置
    ret |= parse_gateway_uart_485_cfg(gw_cfg_obj, &gw_cfg->uart_485_cfg);
    // 解析网关定时配置
    ret |= parse_gateway_timed_cfg(gw_cfg_obj, &gw_cfg->timed_cfg);

    return ret;
}

int parse_wiota_sys_cfg(const cJSON *data_json, wiota_sys_cfg_t *sys_cfg)
{
    int ret = 0;
    const cJSON *sys_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, WIOTA_SYS_CFG);
    if (!sys_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint8(sys_cfg_obj, SYMBOL_LENGTH, &sys_cfg->symbol_length);
    ret |= parse_uint8(sys_cfg_obj, DLUL_RATIO, &sys_cfg->dlul_ratio);
    ret |= parse_uint8(sys_cfg_obj, GROUP_NUMBER, &sys_cfg->group_number);
    ret |= parse_uint8(sys_cfg_obj, BT_VALUE, &sys_cfg->bt_value);
    ret |= parse_uint32(sys_cfg_obj, SUBSYSTEM_ID, &sys_cfg->subsystem_id);

    return ret;
}

int parse_wiota_act_cfg(const cJSON *data_json, wiota_act_cfg_t *act_cfg)
{
    int ret = 0;
    const cJSON *act_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, WIOTA_ACT_CFG);
    if (!act_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint32(act_cfg_obj, ACTIVE_TIME, &act_cfg->active_time);

    return ret;
}

int parse_wiota_freq_cfg(const cJSON *data_json, wiota_freq_cfg_t *freq_cfg)
{
    int ret = 0;
    const cJSON *freq_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, WIOTA_FREQ_CFG);
    if (!freq_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint8_array(freq_cfg_obj, FREQ_LIST, freq_cfg->freq_list, sizeof(freq_cfg->freq_list));

    return ret;
}

int parse_wiota_power_cfg(const cJSON *data_json, wiota_power_cfg_t *power_cfg)
{
    int ret = 0;
    const cJSON *power_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, WIOTA_POWER_CFG);
    if (!power_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint8(power_cfg_obj, POWER_VALUE, &power_cfg->power);

    return ret;
}

int parse_wiota_rate_cfg(const cJSON *data_json, wiota_rate_cfg_t *rate_cfg)
{
    int ret = 0;
    const cJSON *rate_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, WIOTA_RATE_CFG);
    if (!rate_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint8(rate_cfg_obj, UNICAST_MCS, &rate_cfg->unicast_mcs);
    ret |= parse_uint8(rate_cfg_obj, MID_MODE_STATE, &rate_cfg->mid_mode_state);
    ret |= parse_uint16(rate_cfg_obj, HIGH_MODE_STATE, &rate_cfg->high_mode_state);
    ret |= parse_uint8(rate_cfg_obj, BROADCAST_MCS, &rate_cfg->broadcast_mcs);
    ret |= parse_uint8(rate_cfg_obj, CCE_CRC_TYPE, &rate_cfg->crc_type);
    ret |= parse_uint8(rate_cfg_obj, BC_SEND_ROUND, &rate_cfg->bc_send_round);
    ret |= parse_uint8(rate_cfg_obj, UC_RESEND_TIMES, &rate_cfg->uc_resend_times);

    return ret;
}

int parse_wiota_paging_tx_cfg(const cJSON *data_json, wiota_paging_tx_cfg_t *paging_tx_cfg)
{
    int ret = 0;
    const cJSON *paging_tx_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, WIOTA_PAGING_TX_CFG);
    if (!paging_tx_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint8(paging_tx_cfg_obj, PAGING_TX_FREQ, &paging_tx_cfg->freq);
    // ret |= parse_uint8(paging_tx_cfg_obj, "spectrum_idx", &paging_tx_cfg->spectrum_idx);
    // ret |= parse_uint8(paging_tx_cfg_obj, "bandwidth", &paging_tx_cfg->bandwidth);
    ret |= parse_uint8(paging_tx_cfg_obj, SYMBOL_LENGTH, &paging_tx_cfg->symbol_length);
    ret |= parse_uint16(paging_tx_cfg_obj, AWAKEN_ID, &paging_tx_cfg->awaken_id);
    ret |= parse_uint32(paging_tx_cfg_obj, SEND_TIME, &paging_tx_cfg->send_time);
    ret |= parse_uint32(paging_tx_cfg_obj, PAGING_TX_MODE, &paging_tx_cfg->mode);

    return ret;
}

int parse_wiota_sync_paging_cfg(const cJSON *data_json, wiota_sync_paging_cfg_t *sync_paging_cfg)
{
    int ret = 0;
    const cJSON *sync_paging_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, WIOTA_SYNC_PAGING_CFG);
    if (!sync_paging_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint32(sync_paging_cfg_obj, DEV_ID, &sync_paging_cfg->dev_id);
    // ret |= parse_uint32(sync_paging_cfg_obj, "fn_index", &sync_paging_cfg->fn_index);
    ret |= parse_uint32(sync_paging_cfg_obj, PERIOD, &sync_paging_cfg->detection_period);
    ret |= parse_uint32(sync_paging_cfg_obj, SEND_ROUND, &sync_paging_cfg->send_round);
    ret |= parse_uint32(sync_paging_cfg_obj, FRAME_NUM, &sync_paging_cfg->continue_fn);

    return ret;
}

int parse_wiota_ts_cfg(const cJSON *data_json, wiota_ts_cfg_t *ts_cfg)
{
    int ret = 0;
    const cJSON *ts_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, WIOTA_TS_CFG);
    if (!ts_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint8(ts_cfg_obj, TS_MODE, &ts_cfg->ts_mode);
    ret |= parse_uint8(ts_cfg_obj, DEV_TYPE, &ts_cfg->dev_type);
    ret |= parse_uint8(ts_cfg_obj, TS_PERIOD, &ts_cfg->ts_period);

    return ret;
}

#ifdef WIOTA_SUBF_MODE_SUPPORT
int parse_wiota_subf_mode_cfg(const cJSON *data_json, wiota_subf_mode_cfg_t *subf_cfg)
{
    int ret = 0;
    const cJSON *subf_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, WIOTA_SUBF_MODE_CFG);
    if (!subf_cfg_obj)
    {
        return -1;
    }
    ret |= parse_uint8(subf_cfg_obj, WIOTA_SUBF_MODE, &subf_cfg->ul_subf_mode);
    ret |= parse_uint8(subf_cfg_obj, WIOTA_SUBF_BLOCK_SIZE, &subf_cfg->block_size);
    ret |= parse_uint8(subf_cfg_obj, SEND_ROUND, &subf_cfg->dl_subf_send_round);

    return ret;
}
#endif

int parse_wiota_cfg(const cJSON *data_json, wiota_cfg_t *wiota_cfg)
{
    int ret = 0;
    const cJSON *wiota_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, WIOTA_CFG);
    if (!wiota_cfg_obj)
    {
        return -1;
    }

    ret |= parse_wiota_sys_cfg(wiota_cfg_obj, &wiota_cfg->sys_cfg);
    ret |= parse_wiota_act_cfg(wiota_cfg_obj, &wiota_cfg->act_cfg);
    ret |= parse_wiota_freq_cfg(wiota_cfg_obj, &wiota_cfg->freq_cfg);
    ret |= parse_wiota_power_cfg(wiota_cfg_obj, &wiota_cfg->power_cfg);
    ret |= parse_wiota_rate_cfg(wiota_cfg_obj, &wiota_cfg->rate_cfg);
    ret |= parse_wiota_paging_tx_cfg(wiota_cfg_obj, &wiota_cfg->paging_tx_cfg);
    ret |= parse_wiota_sync_paging_cfg(wiota_cfg_obj, &wiota_cfg->sync_paging_cfg);
    ret |= parse_wiota_ts_cfg(wiota_cfg_obj, &wiota_cfg->ts_cfg);
#ifdef WIOTA_SUBF_MODE_SUPPORT
    ret |= parse_wiota_subf_mode_cfg(wiota_cfg_obj, &wiota_cfg->subf_cfg);
#endif
    return ret;
}

int parse_sync_cfg(const cJSON *data_json, sync_cfg_t *sync_cfg)
{
    int ret = 0;
    const cJSON *sync_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, SYNC_ASSISTANT_CFG);
    if (!sync_cfg_obj)
    {
        return -1;
    }

    ret |= parse_uint8(sync_cfg_obj, SYNC_DEF_FLAG, &sync_cfg->user_def_flag);
    ret |= parse_uint8(sync_cfg_obj, SYNC_WORK_MODE, &sync_cfg->mode);
    ret |= parse_uint8(sync_cfg_obj, SYNC_SYMBOL_LENGTH, &sync_cfg->symbol_len);
    ret |= parse_uint8(sync_cfg_obj, SYNC_BAND_WIDTH, &sync_cfg->bt);
    ret |= parse_uint8(sync_cfg_obj, SYNC_MCS, &sync_cfg->mcs);
    ret |= parse_uint8(sync_cfg_obj, SYNC_POWER, &sync_cfg->power);
    ret |= parse_uint16(sync_cfg_obj, SYNC_FREQ, &sync_cfg->freq);
    ret |= parse_uint8(sync_cfg_obj, SYNC_WIOTA_LOG, &sync_cfg->wiota_log);
    ret |= parse_uint32(sync_cfg_obj, SYNC_CYCLE, &sync_cfg->sync_cycle);
    ret |= parse_uint8(sync_cfg_obj, SYNC_WDT, &sync_cfg->watchdog_flag);
    ret |= parse_uint16_array(sync_cfg_obj, SYNC_WHITELIST, sync_cfg->whitelist, MAX_WHITELIST_NUM);

    return ret;
}

int parse_slot_send_cfg(const cJSON *data_json, slot_send_cfg_t *slot_send_cfg)
{
    int ret = 0;
    const cJSON *slot_send_cfg_obj = cJSON_GetObjectItemCaseSensitive(data_json, SLOT_SEND_CFG);
    if (!slot_send_cfg_obj)
    {
        return -1;
    }

    ret |= parse_uint32(slot_send_cfg_obj, ALIVE_FUNCTION, &slot_send_cfg->alive_timeout);
    ret |= parse_uint32(slot_send_cfg_obj, PERIOD, &slot_send_cfg->data_transport_period);
    ret |= parse_uint16(slot_send_cfg_obj, UL_MAX_LEN, &slot_send_cfg->ul_max_len);
    ret |= parse_uint16(slot_send_cfg_obj, DL_MAX_LEN, &slot_send_cfg->dl_max_len);
    ret |= parse_uint8(slot_send_cfg_obj, UL_RESEND_TIMES, &slot_send_cfg->ul_resend_times);
    ret |= parse_uint8(slot_send_cfg_obj, DL_RESEND_TIMES, &slot_send_cfg->dl_resend_times);
    ret |= parse_uint8(slot_send_cfg_obj, UL_MCS, &slot_send_cfg->ul_mcs);
    ret |= parse_uint8(slot_send_cfg_obj, DL_MCS, &slot_send_cfg->dl_mcs);
    ret |= parse_uint16(slot_send_cfg_obj, BC_FN_SEND_PERIOD, &slot_send_cfg->bc_frame_send_period);
    ret |= parse_uint16(slot_send_cfg_obj, DEVICE_ACCESS_MAX, &slot_send_cfg->device_access_max);
    ret |= parse_uint32(slot_send_cfg_obj, REAL_PERIOD, &slot_send_cfg->real_data_transport_period);

    return ret;
}

int add_gateway_base_cfg(cJSON *data_json, const gw_base_cfg_t *base_cfg)
{
    cJSON *base_cfg_obj = cJSON_CreateObject();
    if (!base_cfg_obj)
    {
        return 1;
    }
    cJSON *dev_serial_obj = cJSON_CreateArray();
    if (!dev_serial_obj)
    {
        cJSON_Delete(base_cfg_obj);
        return 2;
    }

    cJSON_AddStringToObject(base_cfg_obj, COMPANY, base_cfg->company);
    for (int i = 0; i < sizeof(base_cfg->dev_serial); i++)
    {
        cJSON_AddItemToArray(dev_serial_obj, cJSON_CreateNumber(base_cfg->dev_serial[i]));
    }
    cJSON_AddItemToObject(base_cfg_obj, DEV_SERIAL, dev_serial_obj);
    cJSON_AddNumberToObject(base_cfg_obj, DEV_ID, base_cfg->dev_id);
    cJSON_AddStringToObject(base_cfg_obj, HARDWARE_VERSION, base_cfg->hardware_version);
    cJSON_AddStringToObject(base_cfg_obj, SOFTWARE_VERSION, CFG_SOFTWARE_VERSION);

    cJSON_AddItemToObject(data_json, GW_BASE_CFG, base_cfg_obj);

    return 0;
}

int add_gateway_auth_cfg(cJSON *data_json, const gw_auth_cfg_t *auth_cfg)
{
    cJSON *aut_cfg_obj = cJSON_CreateObject();
    if (!aut_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(aut_cfg_obj, WORK_MODE, auth_cfg->work_mode);
    cJSON_AddNumberToObject(aut_cfg_obj, GW_VERITY, auth_cfg->gw_verity);
    cJSON_AddNumberToObject(aut_cfg_obj, KEY_TYPE, auth_cfg->key_type);
    cJSON_AddStringToObject(aut_cfg_obj, KEY, auth_cfg->key);

    cJSON_AddItemToObject(data_json, GW_AUTH_CFG, aut_cfg_obj);

    return 0;
}

int add_gateway_id_mng_cfg(cJSON *data_json, const gw_id_manager_cfg_t *id_mng_cfg)
{
    cJSON *id_mng_cfg_obj = cJSON_CreateObject();
    if (!id_mng_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(id_mng_cfg_obj, ASSIGN_START_ADDR, id_mng_cfg->assign_start_addr);
    cJSON_AddNumberToObject(id_mng_cfg_obj, ASSIGN_END_ADDR, id_mng_cfg->assign_end_addr);
    cJSON_AddNumberToObject(id_mng_cfg_obj, ADDR_NUM, id_mng_cfg->addr_num);

    cJSON_AddItemToObject(data_json, GW_ID_MNG_CFG, id_mng_cfg_obj);

    return 0;
}

int add_gateway_net_policy_cfg(cJSON *data_json, const gw_net_policy_cfg_t *net_policy_cfg)
{
    cJSON *net_policy_cfg_obj = cJSON_CreateObject();
    if (!net_policy_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(net_policy_cfg_obj, NETDEV_POLICY, net_policy_cfg->netdev_policy);
    cJSON_AddStringToObject(net_policy_cfg_obj, NETDEV_NAME, net_policy_cfg->netdev_name);

    cJSON_AddItemToObject(data_json, NETDEV_POLICY, net_policy_cfg_obj);

    return 0;
}

int add_gateway_net_if_cfg(cJSON *data_json, const gw_net_if_cfg_t *net_if_cfg)
{
    cJSON *net_if_cfg_obj = cJSON_CreateObject();
    if (!net_if_cfg_obj)
    {
        return 1;
    }
    cJSON *mac_obj = cJSON_CreateArray();
    if (!mac_obj)
    {
        cJSON_Delete(net_if_cfg_obj);
        return 2;
    }

    cJSON_AddStringToObject(net_if_cfg_obj, NET_DEV_STATE, net_if_cfg->netdev_state);
    cJSON_AddNumberToObject(net_if_cfg_obj, STATIC_IP, net_if_cfg->static_ip);
    for (int i = 0; i < sizeof(net_if_cfg->mac); i++)
    {
        cJSON_AddItemToArray(mac_obj, cJSON_CreateNumber(net_if_cfg->mac[i]));
    }
    cJSON_AddItemToObject(net_if_cfg_obj, MAC_ADDR, mac_obj);
    cJSON_AddStringToObject(net_if_cfg_obj, IP_ADDR, net_if_cfg->ip_addr);
    cJSON_AddStringToObject(net_if_cfg_obj, GATEWAY_ADDR, net_if_cfg->gateway_addr);
    cJSON_AddStringToObject(net_if_cfg_obj, MASK_ADDR, net_if_cfg->mask_addr);
    cJSON_AddStringToObject(net_if_cfg_obj, PRIMARY_DNS, net_if_cfg->primary_dns);
    cJSON_AddStringToObject(net_if_cfg_obj, SECONDARY_DNS, net_if_cfg->secondary_dns);

    cJSON_AddItemToObject(data_json, NET_INTERFACE, net_if_cfg_obj);

    return 0;
}

int add_gateway_wifi_cfg(cJSON *data_json, const gw_wifi_cfg_t *wifi_cfg)
{
    cJSON *wifi_cfg_obj = cJSON_CreateObject();
    if (!wifi_cfg_obj)
    {
        return 1;
    }
    cJSON *mac_obj = cJSON_CreateArray();
    if (!mac_obj)
    {
        cJSON_Delete(wifi_cfg_obj);
        return 2;
    }

    cJSON_AddStringToObject(wifi_cfg_obj, NET_DEV_STATE, wifi_cfg->netdev_state);
    cJSON_AddNumberToObject(wifi_cfg_obj, STATIC_IP, wifi_cfg->static_ip);
    for (int i = 0; i < sizeof(wifi_cfg->mac); i++)
    {
        cJSON_AddItemToArray(mac_obj, cJSON_CreateNumber(wifi_cfg->mac[i]));
    }
    cJSON_AddItemToObject(wifi_cfg_obj, MAC_ADDR, mac_obj);
    cJSON_AddStringToObject(wifi_cfg_obj, IP_ADDR, wifi_cfg->ip_addr);
    cJSON_AddStringToObject(wifi_cfg_obj, GATEWAY_ADDR, wifi_cfg->gateway_addr);
    cJSON_AddStringToObject(wifi_cfg_obj, MASK_ADDR, wifi_cfg->mask_addr);
    cJSON_AddStringToObject(wifi_cfg_obj, PRIMARY_DNS, wifi_cfg->primary_dns);
    cJSON_AddStringToObject(wifi_cfg_obj, SECONDARY_DNS, wifi_cfg->secondary_dns);
    cJSON_AddStringToObject(wifi_cfg_obj, USERNAME, wifi_cfg->username);
    cJSON_AddStringToObject(wifi_cfg_obj, PASSWORD, wifi_cfg->password);

    cJSON_AddItemToObject(data_json, GW_WIFI_CFG, wifi_cfg_obj);

    return 0;
}

int add_gateway_cat1_cfg(cJSON *data_json, const gw_cat1_cfg_t *cat1_cfg)
{
    cJSON *cat1_cfg_obj = cJSON_CreateObject();
    if (!cat1_cfg_obj)
    {
        return 1;
    }
    cJSON *mac_obj = cJSON_CreateArray();
    if (!mac_obj)
    {
        cJSON_Delete(cat1_cfg_obj);
        return 2;
    }

    cJSON_AddStringToObject(cat1_cfg_obj, NET_DEV_STATE, cat1_cfg->netdev_state);
    for (int i = 0; i < sizeof(cat1_cfg->mac); i++)
    {
        cJSON_AddItemToArray(mac_obj, cJSON_CreateNumber(cat1_cfg->mac[i]));
    }
    cJSON_AddItemToObject(cat1_cfg_obj, MAC_ADDR, mac_obj);
    cJSON_AddStringToObject(cat1_cfg_obj, IP_ADDR, cat1_cfg->ip_addr);
    cJSON_AddStringToObject(cat1_cfg_obj, GATEWAY_ADDR, cat1_cfg->gateway_addr);
    cJSON_AddStringToObject(cat1_cfg_obj, MASK_ADDR, cat1_cfg->mask_addr);
    cJSON_AddStringToObject(cat1_cfg_obj, CAT1_CSQ, cat1_cfg->csq);
    cJSON_AddStringToObject(cat1_cfg_obj, CAT1_CCID, cat1_cfg->ccid);
    cJSON_AddStringToObject(cat1_cfg_obj, CAT1_CIMI, cat1_cfg->cimi);
    cJSON_AddStringToObject(cat1_cfg_obj, CAT1_GSN, cat1_cfg->gsn);
    cJSON_AddStringToObject(cat1_cfg_obj, CAT1_APN, cat1_cfg->apn);

    cJSON_AddItemToObject(data_json, GW_CAT1_CFG, cat1_cfg_obj);

    return 0;
}

int add_gateway_bt_cfg(cJSON *data_json, const gw_bt_cfg_t *bt_cfg)
{
    cJSON *bt_cfg_obj = cJSON_CreateObject();
    if (!bt_cfg_obj)
    {
        return 1;
    }

    cJSON_AddStringToObject(bt_cfg_obj, MAC_ADDR, bt_cfg->mac);

    cJSON_AddItemToObject(data_json, GW_BT_CFG, bt_cfg_obj);

    return 0;
}

int add_gateway_mqtt_server_cfg(cJSON *data_json, const gw_mqtt_server_cfg_t *mqtt_cfg)
{
    cJSON *mqtt_cfg_obj = cJSON_CreateObject();
    if (!mqtt_cfg_obj)
    {
        return 1;
    }

    cJSON_AddStringToObject(mqtt_cfg_obj, URL, mqtt_cfg->url);
    cJSON_AddNumberToObject(mqtt_cfg_obj, MQTT_PORT, mqtt_cfg->port);
    cJSON_AddStringToObject(mqtt_cfg_obj, CLIENT_ID, mqtt_cfg->client_id);
    cJSON_AddStringToObject(mqtt_cfg_obj, USERNAME, mqtt_cfg->username);
    cJSON_AddStringToObject(mqtt_cfg_obj, PASSWORD, mqtt_cfg->password);
    cJSON_AddNumberToObject(mqtt_cfg_obj, MQTT_QOS, mqtt_cfg->qos);

    cJSON_AddItemToObject(data_json, GW_MQTT_CFG, mqtt_cfg_obj);

    return 0;
}

int add_gateway_data_cfg(cJSON *data_json, const gw_data_cfg_t *data_cfg)
{
    cJSON *ul_data_cfg_obj = cJSON_CreateObject();
    if (!ul_data_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(ul_data_cfg_obj, UP_ENCODE, data_cfg->up_encode);
    cJSON_AddNumberToObject(ul_data_cfg_obj, UL_DATA_FLOW, data_cfg->ul_data_flow);
    cJSON_AddNumberToObject(ul_data_cfg_obj, UL_DATA_PRINT, data_cfg->ul_data_print);
    cJSON_AddNumberToObject(ul_data_cfg_obj, DL_DATA_PRINT, data_cfg->dl_data_print);

    cJSON_AddItemToObject(data_json, GW_DATA_CFG, ul_data_cfg_obj);

    return 0;
}

int add_gateway_wtd_cfg(cJSON *data_json, const gw_wtd_cfg_t *wtd_cfg)
{
    cJSON *wtd_cfg_obj = cJSON_CreateObject();
    if (!wtd_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(wtd_cfg_obj, WTD_STATE, wtd_cfg->wtd_state);

    cJSON_AddItemToObject(data_json, GW_WTD_CFG, wtd_cfg_obj);

    return 0;
}

int add_gateway_ftp_log_cfg(cJSON *data_json, const gw_ftp_log_cfg_t *log_cfg)
{
    cJSON *log_cfg_obj = cJSON_CreateObject();
    if (!log_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(log_cfg_obj, FTP_LOG, log_cfg->ftp_log);
    cJSON_AddNumberToObject(log_cfg_obj, FTP_PORT, log_cfg->port);
    cJSON_AddStringToObject(log_cfg_obj, IP_ADDR, log_cfg->ip_addr);
    cJSON_AddStringToObject(log_cfg_obj, USERNAME, log_cfg->username);
    cJSON_AddStringToObject(log_cfg_obj, PASSWORD, log_cfg->password);
    cJSON_AddStringToObject(log_cfg_obj, SERVER_PATH, log_cfg->server_path);

    cJSON_AddItemToObject(data_json, FTP_LOG, log_cfg_obj);

    return 0;
}

int add_gateway_log_switch_cfg(cJSON *data_json, const gw_log_switch_cfg_t *log_switch_cfg)
{
    cJSON *log_switch_cfg_obj = cJSON_CreateObject();
    if (!log_switch_cfg_obj)
    {
        return 1;
    }

    cJSON_AddStringToObject(log_switch_cfg_obj, GW_LOG_UART, log_switch_cfg->log_uart);
    cJSON_AddNumberToObject(log_switch_cfg_obj, GW_AP_LOG_OUTPUT, log_switch_cfg->ap_log_output);

    cJSON_AddItemToObject(data_json, GW_LOG_SWITCH_CFG, log_switch_cfg_obj);

    return 0;
}

int add_gateway_uart_485_cfg(cJSON *data_json, const gw_uart_485_cfg_t *uart_485_cfg)
{
    cJSON *uart_485_cfg_obj = cJSON_CreateObject();
    if (!uart_485_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(uart_485_cfg_obj, GW_UART_485_BAUD, uart_485_cfg->baud_rate);

    cJSON_AddItemToObject(data_json, GW_UART_485_CFG, uart_485_cfg_obj);

    return 0;
}

int add_gateway_timed_cfg(cJSON *data_json, const gw_timed_cfg_t *timed_cfg)
{
    cJSON *timed_cfg_obj = cJSON_CreateObject();
    if (!timed_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(timed_cfg_obj, GW_TIME, timed_cfg->time);
    cJSON_AddNumberToObject(timed_cfg_obj, GW_UNABNORMAL_TIME, timed_cfg->abnormal_time);
    cJSON_AddNumberToObject(timed_cfg_obj, GW_ROLL_CALL_TIME, timed_cfg->roll_call_time);
    cJSON_AddNumberToObject(timed_cfg_obj, GW_ROLL_CALL_RTO, timed_cfg->rc_rto);

    cJSON_AddItemToObject(data_json, GW_TIMED_CFG, timed_cfg_obj);

    return 0;
}

int add_gateway_cfg(cJSON *data_json, const gateway_cfg_t *gw_cfg)
{
    cJSON *gw_cfg_obj = cJSON_CreateObject();

    if (!gw_cfg_obj)
    {
        return 1;
    }

    // 网关基础信息配置
    add_gateway_base_cfg(gw_cfg_obj, &gw_cfg->base_cfg);
    // 网关鉴权信息配置
    add_gateway_auth_cfg(gw_cfg_obj, &gw_cfg->auth_cfg);
    // id管理地址配置
    add_gateway_id_mng_cfg(gw_cfg_obj, &gw_cfg->id_mng_cfg);
    // 网络配置
    add_gateway_net_policy_cfg(gw_cfg_obj, &gw_cfg->net_policy_cfg);
    add_gateway_net_if_cfg(gw_cfg_obj, &gw_cfg->net_if_cfg);
    add_gateway_wifi_cfg(gw_cfg_obj, &gw_cfg->wifi_cfg);
    add_gateway_cat1_cfg(gw_cfg_obj, &gw_cfg->cat1_cfg);
    // udp配置
    add_gateway_bt_cfg(gw_cfg_obj, &gw_cfg->bt_cfg);
    // mqtt服务器配置
    add_gateway_mqtt_server_cfg(gw_cfg_obj, &gw_cfg->mqtt_server_cfg);
    // 上下行数据配置
    add_gateway_data_cfg(gw_cfg_obj, &gw_cfg->data_cfg);
    // 看门狗配置
    add_gateway_wtd_cfg(gw_cfg_obj, &gw_cfg->wtd_cfg);
    // log配置
    add_gateway_ftp_log_cfg(gw_cfg_obj, &gw_cfg->log_cfg);
    // log切换配置
    add_gateway_log_switch_cfg(gw_cfg_obj, &gw_cfg->log_switch_cfg);
    // 485配置
    add_gateway_uart_485_cfg(gw_cfg_obj, &gw_cfg->uart_485_cfg);
    // 定时配置
    add_gateway_timed_cfg(gw_cfg_obj, &gw_cfg->timed_cfg);

    cJSON_AddItemToObject(data_json, GW_CFG, gw_cfg_obj);

    return 0;
}

int add_wiota_version(cJSON *data_json, const wiota_version_t *wiota_version)
{
    cJSON *wiota_version_obj = cJSON_CreateObject();
    if (!wiota_version_obj)
    {
        return 1;
    }

    cJSON_AddStringToObject(wiota_version_obj, WIOTA_VERSION, wiota_version->uc8088_version);
    cJSON_AddStringToObject(wiota_version_obj, GIT_INFO, wiota_version->git_info_8088);
    cJSON_AddStringToObject(wiota_version_obj, MAKE_TIME, wiota_version->make_time_8088);
    cJSON_AddNumberToObject(wiota_version_obj, CCE_VERSION, wiota_version->cce_version);

    cJSON_AddItemToObject(data_json, WIOTA_VERSION, wiota_version_obj);

    return 0;
}

int add_wiota_sys_cfg(cJSON *data_json, const wiota_sys_cfg_t *sys_cfg)
{
    cJSON *sys_cfg_obj = cJSON_CreateObject();
    if (!sys_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(sys_cfg_obj, SYMBOL_LENGTH, sys_cfg->symbol_length);
    cJSON_AddNumberToObject(sys_cfg_obj, DLUL_RATIO, sys_cfg->dlul_ratio);
    cJSON_AddNumberToObject(sys_cfg_obj, GROUP_NUMBER, sys_cfg->group_number);
    cJSON_AddNumberToObject(sys_cfg_obj, BT_VALUE, sys_cfg->bt_value);
    cJSON_AddNumberToObject(sys_cfg_obj, SUBSYSTEM_ID, sys_cfg->subsystem_id);

    cJSON_AddItemToObject(data_json, WIOTA_SYS_CFG, sys_cfg_obj);

    return 0;
}

int add_wiota_act_cfg(cJSON *data_json, const wiota_act_cfg_t *act_cfg)
{
    cJSON *act_cfg_obj = cJSON_CreateObject();
    if (!act_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(act_cfg_obj, ACTIVE_TIME, act_cfg->active_time);

    cJSON_AddItemToObject(data_json, WIOTA_ACT_CFG, act_cfg_obj);

    return 0;
}

int add_wiota_freq_cfg(cJSON *data_json, const wiota_freq_cfg_t *freq_cfg)
{
    cJSON *freq_cfg_obj = cJSON_CreateObject();
    if (!freq_cfg_obj)
    {
        return 1;
    }
    cJSON *freq_list_obj = cJSON_CreateArray();
    if (!freq_list_obj)
    {
        cJSON_Delete(freq_cfg_obj);
        return 2;
    }

    for (int i = 0; i < sizeof(freq_cfg->freq_list); i++)
    {
        cJSON_AddItemToArray(freq_list_obj, cJSON_CreateNumber(freq_cfg->freq_list[i]));
    }
    cJSON_AddItemToObject(freq_cfg_obj, FREQ_LIST, freq_list_obj);
    cJSON_AddNumberToObject(freq_cfg_obj, CURRENT_FREQ, freq_cfg->current_freq);

    cJSON_AddItemToObject(data_json, WIOTA_FREQ_CFG, freq_cfg_obj);

    return 0;
}

int add_wiota_power_cfg(cJSON *data_json, const wiota_power_cfg_t *power_cfg)
{
    cJSON *power_cfg_obj = cJSON_CreateObject();
    if (!power_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(power_cfg_obj, POWER_VALUE, power_cfg->power);

    cJSON_AddItemToObject(data_json, WIOTA_POWER_CFG, power_cfg_obj);

    return 0;
}

int add_wiota_rate_cfg(cJSON *data_json, const wiota_rate_cfg_t *rate_cfg)
{
    cJSON *rate_cfg_obj = cJSON_CreateObject();
    if (!rate_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(rate_cfg_obj, UNICAST_MCS, rate_cfg->unicast_mcs);
    cJSON_AddNumberToObject(rate_cfg_obj, MID_MODE_STATE, rate_cfg->mid_mode_state);
    cJSON_AddNumberToObject(rate_cfg_obj, HIGH_MODE_STATE, rate_cfg->high_mode_state);
    cJSON_AddNumberToObject(rate_cfg_obj, BROADCAST_MCS, rate_cfg->broadcast_mcs);
    cJSON_AddNumberToObject(rate_cfg_obj, CCE_CRC_TYPE, rate_cfg->crc_type);
    cJSON_AddNumberToObject(rate_cfg_obj, BC_SEND_ROUND, rate_cfg->bc_send_round);
    cJSON_AddNumberToObject(rate_cfg_obj, UC_RESEND_TIMES, rate_cfg->uc_resend_times);

    cJSON_AddItemToObject(data_json, WIOTA_RATE_CFG, rate_cfg_obj);

    return 0;
}

int add_wiota_paging_tx_cfg(cJSON *data_json, const wiota_paging_tx_cfg_t *paging_tx_cfg)
{
    cJSON *paging_tx_cfg_obj = cJSON_CreateObject();
    if (!paging_tx_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(paging_tx_cfg_obj, PAGING_TX_FREQ, paging_tx_cfg->freq);
    // cJSON_AddNumberToObject(paging_tx_cfg_obj, "spectrum_idx", paging_tx_cfg->spectrum_idx);
    // cJSON_AddNumberToObject(paging_tx_cfg_obj, "bandwidth", paging_tx_cfg->bandwidth);
    cJSON_AddNumberToObject(paging_tx_cfg_obj, SYMBOL_LENGTH, paging_tx_cfg->symbol_length);
    cJSON_AddNumberToObject(paging_tx_cfg_obj, AWAKEN_ID, paging_tx_cfg->awaken_id);
    cJSON_AddNumberToObject(paging_tx_cfg_obj, SEND_TIME, paging_tx_cfg->send_time);
    cJSON_AddNumberToObject(paging_tx_cfg_obj, PAGING_TX_MODE, paging_tx_cfg->mode);

    cJSON_AddItemToObject(data_json, WIOTA_PAGING_TX_CFG, paging_tx_cfg_obj);

    return 0;
}

int add_wiota_sync_paging_cfg(cJSON *data_json, const wiota_sync_paging_cfg_t *sync_paging_cfg)
{
    cJSON *sync_paging_cfg_obj = cJSON_CreateObject();
    if (!sync_paging_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(sync_paging_cfg_obj, DEV_ID, sync_paging_cfg->dev_id);
    // cJSON_AddNumberToObject(sync_paging_cfg_obj, "fn_index", sync_paging_cfg->fn_index);
    cJSON_AddNumberToObject(sync_paging_cfg_obj, PERIOD, sync_paging_cfg->detection_period);
    cJSON_AddNumberToObject(sync_paging_cfg_obj, SEND_ROUND, sync_paging_cfg->send_round);
    cJSON_AddNumberToObject(sync_paging_cfg_obj, FRAME_NUM, sync_paging_cfg->continue_fn);

    cJSON_AddItemToObject(data_json, WIOTA_SYNC_PAGING_CFG, sync_paging_cfg_obj);

    return 0;
}

int add_wiota_ts_cfg(cJSON *data_json, const wiota_ts_cfg_t *ts_cfg)
{
    cJSON *ts_cfg_obj = cJSON_CreateObject();
    if (!ts_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(ts_cfg_obj, TS_MODE, ts_cfg->ts_mode);
    cJSON_AddNumberToObject(ts_cfg_obj, DEV_TYPE, ts_cfg->dev_type);
    cJSON_AddNumberToObject(ts_cfg_obj, TS_PERIOD, ts_cfg->ts_period);

    cJSON_AddItemToObject(data_json, WIOTA_TS_CFG, ts_cfg_obj);

    return 0;
}

#ifdef WIOTA_SUBF_MODE_SUPPORT
int add_wiota_subf_mode_cfg(cJSON *data_json, const wiota_subf_mode_cfg_t *subf_cfg)
{
    cJSON *subf_cfg_obj = cJSON_CreateObject();
    if (!subf_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(subf_cfg_obj, WIOTA_SUBF_MODE, subf_cfg->ul_subf_mode);
    cJSON_AddNumberToObject(subf_cfg_obj, WIOTA_SUBF_BLOCK_SIZE, subf_cfg->block_size);
    cJSON_AddNumberToObject(subf_cfg_obj, SEND_ROUND, subf_cfg->dl_subf_send_round);

    cJSON_AddItemToObject(data_json, WIOTA_SUBF_MODE_CFG, subf_cfg_obj);

    return 0;
}
#endif

int add_wiota_cfg(cJSON *data_json, const wiota_cfg_t *wiota_cfg)
{
    cJSON *wiota_cfg_obj = cJSON_CreateObject();

    if (!wiota_cfg_obj)
    {
        return 1;
    }

    // WIoTa子系统配置
    add_wiota_sys_cfg(wiota_cfg_obj, &wiota_cfg->sys_cfg);
    // WIoTa连接态时间配置
    add_wiota_act_cfg(wiota_cfg_obj, &wiota_cfg->act_cfg);
    // WIoTa频点配置
    add_wiota_freq_cfg(wiota_cfg_obj, &wiota_cfg->freq_cfg);
    // WIoTa功率配置
    add_wiota_power_cfg(wiota_cfg_obj, &wiota_cfg->power_cfg);
    // WIoTa速率配置
    add_wiota_rate_cfg(wiota_cfg_obj, &wiota_cfg->rate_cfg);
    // WIoTa低功耗配置
    add_wiota_paging_tx_cfg(wiota_cfg_obj, &wiota_cfg->paging_tx_cfg);
    add_wiota_sync_paging_cfg(wiota_cfg_obj, &wiota_cfg->sync_paging_cfg);
    // WIoTa同步授时配置
    add_wiota_ts_cfg(wiota_cfg_obj, &wiota_cfg->ts_cfg);
#ifdef WIOTA_SUBF_MODE_SUPPORT
    // WIoTa子帧模式配置
    add_wiota_subf_mode_cfg(wiota_cfg_obj, &wiota_cfg->subf_cfg);
#endif
    cJSON_AddItemToObject(data_json, WIOTA_CFG, wiota_cfg_obj);

    return 0;
}

int add_sync_cfg(cJSON *data_json, const sync_cfg_t *sync_cfg)
{
    cJSON *sync_cfg_obj = cJSON_CreateObject();
    if (!sync_cfg_obj)
    {
        return 1;
    }
    cJSON *whilelist_obj = cJSON_CreateArray();
    if (!whilelist_obj)
    {
        cJSON_Delete(sync_cfg_obj);
        return 2;
    }
    cJSON_AddNumberToObject(sync_cfg_obj, SYNC_DEF_FLAG, sync_cfg->user_def_flag);
    cJSON_AddNumberToObject(sync_cfg_obj, SYNC_WORK_MODE, sync_cfg->mode);
    cJSON_AddNumberToObject(sync_cfg_obj, SYNC_SYMBOL_LENGTH, sync_cfg->symbol_len);
    cJSON_AddNumberToObject(sync_cfg_obj, SYNC_BAND_WIDTH, sync_cfg->bt);
    cJSON_AddNumberToObject(sync_cfg_obj, SYNC_MCS, sync_cfg->mcs);
    cJSON_AddNumberToObject(sync_cfg_obj, SYNC_POWER, sync_cfg->power);
    cJSON_AddNumberToObject(sync_cfg_obj, SYNC_FREQ, sync_cfg->freq);
    cJSON_AddNumberToObject(sync_cfg_obj, SYNC_WIOTA_LOG, sync_cfg->wiota_log);
    cJSON_AddNumberToObject(sync_cfg_obj, SYNC_CYCLE, sync_cfg->sync_cycle);
    cJSON_AddNumberToObject(sync_cfg_obj, SYNC_WDT, sync_cfg->watchdog_flag);

    for (int i = 0; i < MAX_WHITELIST_NUM; i++)
    {
        cJSON_AddItemToArray(whilelist_obj, cJSON_CreateNumber(sync_cfg->whitelist[i]));
    }
    cJSON_AddItemToObject(sync_cfg_obj, SYNC_WHITELIST, whilelist_obj);
    cJSON_AddItemToObject(data_json, SYNC_ASSISTANT_CFG, sync_cfg_obj);

    return 0;
}

int add_slot_send_cfg(cJSON *data_json, const slot_send_cfg_t *slot_send_cfg)
{
    cJSON *slot_send_cfg_obj = cJSON_CreateObject();
    if (!slot_send_cfg_obj)
    {
        return 1;
    }

    cJSON_AddNumberToObject(slot_send_cfg_obj, ALIVE_FUNCTION, slot_send_cfg->alive_timeout);
    cJSON_AddNumberToObject(slot_send_cfg_obj, PERIOD, slot_send_cfg->data_transport_period);
    cJSON_AddNumberToObject(slot_send_cfg_obj, UL_MAX_LEN, slot_send_cfg->ul_max_len);
    cJSON_AddNumberToObject(slot_send_cfg_obj, DL_MAX_LEN, slot_send_cfg->dl_max_len);
    cJSON_AddNumberToObject(slot_send_cfg_obj, UL_RESEND_TIMES, slot_send_cfg->ul_resend_times);
    cJSON_AddNumberToObject(slot_send_cfg_obj, DL_RESEND_TIMES, slot_send_cfg->dl_resend_times);
    cJSON_AddNumberToObject(slot_send_cfg_obj, UL_MCS, slot_send_cfg->ul_mcs);
    cJSON_AddNumberToObject(slot_send_cfg_obj, DL_MCS, slot_send_cfg->dl_mcs);
    cJSON_AddNumberToObject(slot_send_cfg_obj, BC_FN_SEND_PERIOD, slot_send_cfg->bc_frame_send_period);
    cJSON_AddNumberToObject(slot_send_cfg_obj, DEVICE_ACCESS_MAX, slot_send_cfg->device_access_max);
    cJSON_AddNumberToObject(slot_send_cfg_obj, REAL_PERIOD, slot_send_cfg->real_data_transport_period);

    cJSON_AddItemToObject(data_json, SLOT_SEND_CFG, slot_send_cfg_obj);

    return 0;
}

int uc_read_static_data(static_data_t *static_data)
{
    int ret = RT_EOK;
    char *root = NULL, *data = NULL;
    unsigned int root_len = 0, data_len = 0;
    unsigned char data_crc32 = 0, data_crc32_tmp = 0;
    cJSON *root_json = NULL, *data_json = NULL;

    /* 从flash读取配置文件，并转换为字符串 */
    root_len = config_file_get_len(CONFIG_FILE_PATH);
    root = rt_malloc(root_len + 4);
    if (root)
    {
        rt_memset(root, 0, root_len + 4);
    }
    else
    {
        ret = RT_ENOMEM;
        TRACE_E("uc_read_static_data malloc fail");
        goto end;
    }
    config_file_read(CONFIG_FILE_PATH, root, root_len);
    // TRACE_I("read config_file len %u:\n%s", root_len, root);

    /* 检验配置文件完整性 */
    root_json = cJSON_Parse(root);
    if (!root_json)
    {
        ret = RT_EIO;
        TRACE_E("get root_json fail");
        goto end;
    }
    parse_uint8(root_json, JSON_DATA_CRC32, &data_crc32);
    parse_uint32(root_json, JSON_DATA_LEN, &data_len);
    data_json = cJSON_GetObjectItemCaseSensitive(root_json, JSON_DATA);
    if (!data_json)
    {
        ret = RT_EIO;
        TRACE_E("get data_json fail");
        goto end;
    }

    data = cJSON_Print(data_json);
    if (data_len != rt_strlen(data))
    {
        ret = RT_EINVAL;
        TRACE_E("uc_read_static_data error, data_len != rt_strlen(data)");
        goto end;
    }

    for (int i = 0; i < data_len; i++)
    {
        data_crc32_tmp += data[i];
    }
    if (data_crc32 != data_crc32_tmp)
    {
        ret = RT_EINVAL;
        TRACE_E("uc_read_static_data error, data_crc32 != data_crc32_tmp");
        goto end;
    }

    /* 将JSON字符串转换成指定数据的结构体 */
    if (0 != parse_gateway_cfg(data_json, &static_data->gateway_cfg))
    {
        ret = 0xff;
    }
    if (0 != parse_wiota_cfg(data_json, &static_data->wiota_cfg))
    {
        ret = 0xff;
    }
    if (0 != parse_sync_cfg(data_json, &static_data->sync_cfg))
    {
        ret = 0xff;
    }
    if (0 != parse_slot_send_cfg(data_json, &static_data->slot_send_cfg))
    {
        ret = 0xff;
    }

    TRACE_I("uc_read_static_data success");

end:
    rt_free(root);
    rt_free(data);
    cJSON_Delete(root_json);

    return ret;
}

int uc_write_static_data(const static_data_t *static_data)
{
    char *root = NULL, *data = NULL;
    unsigned int root_len = 0, data_len = 0;
    unsigned char data_crc32 = 0;
    cJSON *root_json = cJSON_CreateObject();
    cJSON *data_json = cJSON_CreateObject();
    if (!root_json || !data_json)
    {
        goto end;
    }

    /* 将static_data转换成data_json */
    if (add_gateway_cfg(data_json, &static_data->gateway_cfg))
    {
        cJSON_Delete(data_json);
        goto end;
    }
    if (add_wiota_cfg(data_json, &static_data->wiota_cfg))
    {
        cJSON_Delete(data_json);
        goto end;
    }
    if (add_sync_cfg(data_json, &static_data->sync_cfg))
    {
        cJSON_Delete(data_json);
        goto end;
    }
    if (add_slot_send_cfg(data_json, &static_data->slot_send_cfg))
    {
        cJSON_Delete(data_json);
        goto end;
    }

    /* 将data_json按照协议要求处理, 前面加上data_crc32, data_len */
    data = cJSON_Print(data_json);
    if (RT_NULL == data)
    {
        goto end;
    }
    data_len = rt_strlen(data);
    for (int i = 0; i < data_len; i++)
    {
        data_crc32 += data[i];
    }
    rt_free(data);
    cJSON_AddNumberToObject(root_json, JSON_DATA_CRC32, data_crc32);
    cJSON_AddNumberToObject(root_json, JSON_DATA_LEN, data_len);
    cJSON_AddItemToObject(root_json, JSON_DATA, data_json);

    /* 将root_json转换为字符串，写入flash */
    root = cJSON_Print(root_json);
    if (RT_NULL == root)
    {
        goto end;
    }
    root_len = rt_strlen(root);
    // TRACE_I("write config_file len %u:\n%s", root_len, root);
    config_file_write(CONFIG_FILE_PATH, root, root_len);
    rt_free(root);

end:
    cJSON_Delete(root_json);

    return 0;
}

void show_cfg(void)
{
    do
    {
        char *json_str = encode_gateway_all_cfg();
        if (RT_NULL != json_str)
        {
            // 串口buffer为256字节，这里按照200个字节分段打印
            unsigned int json_len = rt_strlen(json_str);
            unsigned int remainder_len = json_len;
            char printf_buf[210];
            unsigned int printf_len = 0;
            while (remainder_len > 0)
            {
                if (remainder_len >= 200)
                    printf_len = 200;
                else
                    printf_len = remainder_len;
                rt_memset(printf_buf, 0, sizeof(printf_buf));
                rt_memcpy(printf_buf, json_str + (json_len - remainder_len), printf_len);
                rt_kprintf("%s", printf_buf);
                remainder_len -= printf_len;
            }
            rt_kprintf("\n");
            rt_free(json_str);
        }
        else
            break;
    } while (1);

#if 0

    char *root = NULL, *data = NULL;
    unsigned int root_len = 0, data_len = 0;
    unsigned char data_crc32 = 0, data_crc32_tmp = 0;
    cJSON *root_json = NULL, *data_json = NULL;

    /* 从flash读取配置文件，并转换为字符串 */
    root_len = config_file_get_len(CONFIG_FILE_PATH);
    root = rt_malloc(root_len + 4);
    if (root)
    {
        rt_memset(root, 0, root_len + 4);
    }
    else
    {
        TRACE_E("show_cfg malloc fail");
        return;
    }
    config_file_read(CONFIG_FILE_PATH, root, root_len);
    rt_kprintf("read config_file len %u:", root_len);
    // 串口buffer为256字节，这里按照200个字节分段打印
    int k = 0;
    char str_end;
    for (; k < root_len / 200; k++)
    {
        // 将root[200 * k + 200]写为\0用以保证只打印200个字节，打印完再还原
        str_end = root[200 * k + 200];
        root[200 * k + 200] = '\0';
        rt_kprintf("%s", &root[200 * k]);
        root[200 * k + 200] = str_end;
    }
    rt_kprintf("%s", &root[200 * k]);

    /* 检验配置文件完整性 */
    root_json = cJSON_Parse(root);
    if (!root_json)
    {
        TRACE_E("get root_json fail");
        goto end;
    }
    parse_uint8(root_json, JSON_DATA_CRC32, &data_crc32);
    parse_uint32(root_json, JSON_DATA_LEN, &data_len);
    data_json = cJSON_GetObjectItemCaseSensitive(root_json, JSON_DATA);
    if (!data_json)
    {
        TRACE_E("get data_json fail");
        goto end;
    }

    data = cJSON_Print(data_json);
    if (data_len != rt_strlen(data))
    {
        TRACE_E("error, data_len != rt_strlen(data)");
        goto end;
    }

    for (int i = 0; i < data_len; i++)
    {
        data_crc32_tmp += data[i];
    }

    if (data_crc32 != data_crc32_tmp)
    {
        TRACE_E("error, data_crc32 != data_crc32_tmp");
    }

end:
    rt_free(root);
    rt_free(data);
    cJSON_Delete(root_json);

#endif

    return;
}

MSH_CMD_EXPORT(show_cfg, read the config file and show it);